/**
 * @class 星座恒星数据代理
 * @author DuskyHuang 圣子
 * @description 提供星座和恒星相关数据和管理。
*/

import { Proxy, decorators, Notifications } from 'cfw';
import { ConstGroup, StarLevel } from 'const';
import { UI } from 'notifications';
const { singleton } = decorators;

@singleton
export class ConstStarsProxy extends Proxy {

    declare public static readonly instance: ConstStarsProxy;
    private constructor() { super(); }

    public get showStars(): boolean { return this._show_stars; }
    public get showStarLevel(): StarLevel { return this._star_show_level; }
    public get showConstLines(): boolean { return this._show_const_lines; }
    public get showConstCults(): boolean { return this._show_const_cults; }
    public get showConsts(): boolean { return this.showConstLines || this.showConstCults }
    public get showConstGroups(): num.int { return this._show_const_groups; }
    public get showConstHemisphere(): 'N' | 'S' | null { return this._show_const_hemisphere; }
    public get cultureStrengthen(): num.pct { return this._const_cult_strength; }
    public get consLineStrengthen(): num.pct { return this._const_line_strength; }

    public getStateByName(name: string): boolean {
        switch (name) {
            case '恒星': return this.showStars;
            case '连线': return this.showConstLines;
            case '形象': return this.showConstCults;
            case '星区': return false; // TODO
            case '星座': return this.showConsts;
            default: return null;
        }
    }

    public static readonly CultureAtt: attenuation  // 文化淡出范围
        = [2, 4.2];

    public static readonly ConstLineAtt: attenuation// 星座连线淡出范围
        = [0.1, 1.5];

    public static readonly StarParticles = {
        TOTAL: 1000,            // 随机恒星总数量
        Window: [-2, 1],        // 窗口指数空间
        Distance: [0.5, 4.5],   // 恒星的光年指数范围
        Scale: [1, 2],          // 恒星的大小范围
    }

    private _show_stars: boolean = true;
    private _star_show_level: StarLevel = StarLevel.LEVEL_5;    // 暂时显示所有星等且不接受通知
    private _show_const_lines: boolean = false;
    private _show_const_cults: boolean = false;
    private _show_const_groups: num.int = ConstGroup.ALL;
    private _show_const_hemisphere: 'N' | 'S' = null;

    private _const_line_strength: num.pct = 0.5;
    private _const_cult_strength: num.pct = 0.5;
    private _lineFadeIn: boolean = false;
    private _cultFadeIn: boolean = false;
    public lineFadeIn(): void { this._const_line_strength = 0; this._lineFadeIn = true; }
    public cultFadeIn(): void { this._const_cult_strength = 0; this._cultFadeIn = true; }

    protected init(): void {
        this.on(STARS, (show: boolean) => this._show_stars = show);
        this.on(LINES, (show: boolean) => this._show_const_lines = show);
        this.on(CULTURES, (show: boolean) => this._show_const_cults = show);
        this.on(CONSTS, (show: boolean) => this._show_const_lines = this._show_const_cults = show);
        this.on(GROUP, (gid: ConstGroup, show: boolean) => {
            show ? this._show_const_groups |= gid : this._show_const_groups &= ~gid;
            this._show_const_hemisphere = null;
        });
        this.on(HEMISPHERE, (ns: 'N' | 'S') => this._show_const_hemisphere = ns);
        this.on(Notifications.Time.TICK, this.onTick);
    }

    protected onTick(dt?: time.sec, tick?: num.int): void {
        if (this._lineFadeIn) {
            this._const_line_strength += dt * 0.25;
            if (this._const_line_strength >= 0.85) this._lineFadeIn = false;
        }
        if (this._cultFadeIn) {
            this._const_cult_strength += dt * 0.25;
            if (this._const_cult_strength >= 0.5) this._cultFadeIn = false;
        }
    }

}
const { Stellar: { STARS, LINES, CULTURES, CONSTS }, Consts: { GROUP, HEMISPHERE } } = UI;

export const constStars = ConstStarsProxy.instance;